import re

def checkip(ip):
    """
    校验一个字符串是否是合法IP地址
    :param ip:
    :return:
    """
    p = re.compile('^((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))$')
    if p.match(ip):
        return True
    else:
        return False

def only_chinese(word):
    """
     校验一个字符串仅包含中文
    :param word:
    :return:
    """
    p = re.compile(r'^[\u4e00-\u9fa5]+$', re.I)
    if p.match(word):
        return True
    else:
        return False

def is_Chinese(word):
    """
     校验一个字符串是否为中文
    :param word:
    :return:
    """
    for ch in word:
        if '\u4e00' <= ch <= '\u9fa5':
            return True
    return False


def is_number(uchar):
    """
    判断一个unicode是否是数字
    :param uchar:
    :return:
    """
    if uchar >= u'/u0030' and uchar<=u'/u0039':
        return True
    else:
        return False


def is_alphabet(uchar):
    """
    判断一个unicode是否是英文字母
    :param uchar:
    :return:
    """
    if (uchar >= u'/u0041' and uchar<=u'/u005a') or (uchar >= u'/u0061' and uchar<=u'/u007a'):
        return True
    else:
        return False


def is_email(email):
    """
        校验一个字符串是否是合法Email地址
        :param ip:
        :return:
        """
    # p = re.compile("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", re.I)
    p = re.compile(r'^\w+([-+.]\w+)*@\w+([-.]\w+)*.\w+([-.]\w+)*$', re.I)
    if p.match(email):
        return True
    else:
        return False


def is_url(url):
    """
        校验一个字符串是否是合法url地址
        :param ip:
        :return:
        """
    # 1. Allow almost any URL
    # p = re.compile(r'^(https?|ftp|file)://.+$', re.I)
    # 2. Require a domain name, and donot allow a username or password
    # p = re.compile(r'^(https?|ftp)://[a-zA-Z0-9-]+(\.[a-zA-Z0-9]+)+$', re.I)
    # 3. Require a domain name, and donot allow a username or password.
    # p = re.compile(r'^((https?|ftp)://|(www|ftp)\.)[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+([/?].*)?$', re.I)
    # 4. Require a domain name and a path that points to an image file. Donot allow a username, password or parameters
    # p = re.compile(r'^(https?|ftp)://[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+(/[\w-]+)*/[\w-]+\.(gif|png|jpg)$', re.I)
    p = re.compile(r'^((https?|ftp)://|(www|ftp)\.)[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+([/?].*)?$', re.I)
    if p.match(url):
        return True
    else:
        return False

# 正确格式为：“XXXX-XXXXXXX”，“XXXX-XXXXXXXX”，“XXX-XXXXXXX”， “XXX-XXXXXXXX”，“XXXXXXX”，“XXXXXXXX”
def is_phone(phone):
    """
        校验一个字符串是否是国内电话号码
        :param ip:
        :return:
        """
    p = re.compile('^((\d{3,4})|\d{3,4}-)?\d{7,8}$')
    if p.match(phone):
        return True
    else:
        return False


def is_telephone(telephone):
    """
        校验一个字符串是否是国内电话号码
        :param ip:
        :return:
        """
    p = re.compile(r"^(13\d|14[5|7]|15\d|166|17[3|6|7]|18\d)\d{8}$", re.I)
    # p = re.compile(r"^1(([35789]\d)|(47))\d{8}$", re.I)
    if p.match(telephone):
        return True
    else:
        return False


def is_qq(qq):
    """
        校验一个字符串是否是腾讯QQ号
        :param ip:
        :return:
        """
    p = re.compile(r"^[1-9][0-9]{4,}$", re.I)
    if p.match(qq):
        return True
    else:
        return False


def is_postcodes(postcodes):
    """
        校验一个字符串是否是中国邮政编码
        :param ip:
        :return:
        """
    p = re.compile(r"^[1-9]\d{5}(?!\d)$", re.I)
    if p.match(postcodes):
        return True
    else:
        return False


def is_idcard(idcard):
    """
        校验一个字符串是否是合法的身份证号
        1、1999年07月01日以前使用15位身份证号，也就是第一代身份证
        2、二代身份证增加位数至18，多出来的3位分别是出生年份的前两个数字和一位校验码
        3、18位身份证各位置代表信息如下：六位数字地址码+八位数字出生日期码+三位顺序码+一位校验码
        4、顺序码的前两位代表当地派出所代码，第三位是对同年、同月、同日出生的人编定的顺序号，顺序码的奇数分配给男性，偶数分配给女性。
        5、校验码，身份证号18位，前17位为本体码，最后一位是算出来的校验码。校验规则如下：
            前17位分别乘以【7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2】
            然后将17个乘积加一块取余11得到一个0-10范围的数字
            0-10分别对应【1,0,x,9,8,7,6,5,4,3,2】即校验位数字
            出现 x 是因为校验码为10但为了保证号码长度不变，换成了 x
        :param ip:
        :return:
        """
    p = re.compile(r"^\d{15}|\d{}18$", re.I)
    if p.match(idcard):
        if len(idcard) == 18:
            weighted = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
            check_number = ['1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2']
            sum = 0
            for i in range(0, 17):
                sum += int(idcard[i]) * weighted[i]
            sum %= 11
            if check_number[sum].upper().__eq__(idcard[17]):
                return True
            else:
                return False
        else:
            return True
    else:
        return False


def is_date(datestr):
    """
        验证一个字符串是否是时间格式 yyyy-MM-dd 或  yyyy/MM/dd
        :param ip:
        :return:
        """
    # 1、yyyy-MM-dd格式时间校验：
    # (([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|
    # ((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|
    # ((0[48]|[2468][048]|[3579][26])00))-02-29)$
    #
    # 3、yyyy/MM/dd格式时间校验：
    # (([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\/(((0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01]))|
    # ((0[469]|11)\/(0[1-9]|[12][0-9]|30))|(02\/(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|
    # ((0[48]|[2468][048]|[3579][26])00))\/02\/29)$
    #
    p = re.compile(r"^(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})[-|\/](((0[13578]|1[02])[-|\/](0[1-9]|[12][0-9]|3[01]))|"
                   r"((0[469]|11)[-|\/](0[1-9]|[12][0-9]|30))|(02[-|\/](0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|"
                   r"((0[48]|[2468][048]|[3579][26])00))[-|\/]02[-|\/]29)$", re.I)
    if p.match(datestr):
        return True
    else:
        return False


def is_datetime(datetime_tr):
    """
        验证一个字符串是否是时间格式 yyyy-MM-dd HH:mm:ss 或 yyyy/MM/dd HH:mm:ss
        :param ip:
        :return:
        """
    # 2、yyyy-MM-dd HH:mm:ss格式时间校验：
    # ((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|
    # ((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|
    # ((0[48]|[2468][048]|[3579][26])00))-02-29))
    # \s([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$
    #
    # 4、yyyy/MM/dd HH:mm:ss格式时间校验：
    # ((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\/(((0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01]))|
    # ((0[469]|11)\/(0[1-9]|[12][0-9]|30))|(02\/(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|
    # ((0[48]|[2468][048]|[3579][26])00))\/02\/29))
    # \s([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$
    p = re.compile(r"^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})[-|\/](((0[13578]|1[02])[-|\/](0[1-9]|[12][0-9]|3[01]))|"
                   r"((0[469]|11)[-|\/](0[1-9]|[12][0-9]|30))|(02[-|\/](0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|"
                   r"((0[48]|[2468][048]|[3579][26])00))[-|\/]02[-|\/]29))"
                   r"\s([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$", re.I)
    if p.match(datetime_tr):
        return True
    else:
        return False


def is_month(month):
    """
        验证一年的12个月
        :param ip:
        :return:
        """
    p = re.compile(r"^(0?[1-9]|1[0-2])$", re.I)
    if p.match(month):
        return True
    else:
        return False


def is_day(day):
    """
        验证一个月的31天
        :param ip:
        :return:
        """
    p = re.compile(r"^((0?[1-9])|((1|2)[0-9])|30|31)$", re.I)
    if p.match(day):
        return True
    else:
        return False


def is_powerpassword(password):
    """
        验证一个字符串是否是强密码(字母开头,必须包含大小写字母和数字的组合，可以使用特殊字符，长度在6-18之间)
        :param ip:
        :return:
        """
    p = re.compile(r"^([a-zA-Z])(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{5,17}$", re.I)
    if p.match(password):
        return True
    else:
        return False

if __name__ == '__main__':
    str = "ABcd@1234"
    result = is_powerpassword(str)
    print(result)